import { Component } from 'react';
import './QuestionItem.css'
import axios from 'axios'
import bus from '../../util/bus'
import client from '../../util/client';
export default class QuestionItem extends Component {

  constructor(props) {
    super(props);
    this.state = {
      // questionInit表示初始无动画状态
      questionInit: true,
      // 以下3个xxxTextSelect表示对应的输入框是否被选中
      titleTextSelect: false,
      inputTextSelect: false,
      outputTextSelect: false,
      client: this.props.client,
    }
    // index表示当前这个组件是第几个QuestionItem组件
    this.index = 0;
    // listenFunc用于设置监听函数的引用，以便于删除
    this.listenFunc = null;
  }

  render () {
    // 解构获取props的值
    const { index, title, input, output, hidden, hiddenHandler, titleHandler, inputHandler, outputHandler } = this.props;
    // 解构获取state的值
    const { questionInit, titleTextSelect, inputTextSelect, outputTextSelect } = this.state;
    // questionClass为 '' 'hidden' 'question-show'分别是无动画，隐藏动画，展示动画
    let questionClass = '';
    if (!questionInit) {
      questionClass = hidden === true ? 'hidden' : 'question-show';
    }
    // arrowClass为 '' 'arrow-down' 'arrow-up'分别是默认箭头向下无动画，箭头向下转动动画，箭头向上转动动画
    let arrowClass = '';
    arrowClass = hidden === false ? 'arrow-down' : 'arrow-up';

    // 接下来3个Class为 '' 和 'xxx-selected'分别是默认样式，和点击修改后展示的样式
    let titleTextClass = '';
    titleTextClass = titleTextSelect === true ? 'title-selected' : '';

    let inputTextClass = '';
    inputTextClass = inputTextSelect === true ? 'input-selected' : '';

    let outputTextClass = '';
    outputTextClass = outputTextSelect === true ? 'output-selected' : '';

    // 这个index表示当前是第几个QuestionItem组件，每次渲染时都要从父组件传入值中获取
    this.index = index;
    return (
      <div className="question-item">
        <div className="line">
          <div className={`${arrowClass} arrow fa fa-angle-down`} onClick={this.changeQuestionState(hiddenHandler)}></div>
        </div>
        <div ref={item => this.item = item} className={`question ${questionClass}`}>

          <div className="discription">
            <h3>题目描述</h3>
            <span className="fa fa-pencil" onClick={this.modifyText('title')}></span>
            <textarea className={`title-text ${titleTextClass}`} value={title} ref={titleText => this.titleText = titleText} readOnly={!titleTextSelect} onChange={this.onChangeHandler('title', titleHandler)}>

            </textarea >
          </div>

          <div className="demo">
            <h4>实例1</h4>
            <div className="demo-description">
              <div className="input-box">
                <span className="fa fa-pencil" onClick={this.modifyText('input')}></span>
                <h4>输入</h4>
                <div className="input">
                  <textarea className={`input-text ${inputTextClass}`} value={input} ref={inputText => this.inputText = inputText} readOnly={!inputTextSelect} onChange={this.onChangeHandler('input', inputHandler)}>

                  </textarea >
                </div>
              </div>

              <div className="output-box">
                <span className="fa fa-pencil" onClick={this.modifyText('output')}></span>
                <h4>返回值</h4>
                <div className="output">
                  <textarea className={`output-text ${outputTextClass}`} value={output} ref={outputText => this.outputText = outputText} readOnly={!outputTextSelect} onChange={this.onChangeHandler('output', outputHandler)}>

                  </textarea >
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    )
  }
  // 点击隐藏展示箭头时，重新设置question的state
  changeQuestionState = (callback) => {
    let that = this;
    return function (e) {
      that.setState({ questionInit: false });
      callback(!that.props.hidden, that.index);
    }
  }
  // 点击修改按钮（铅笔形按钮后调用modifyText返回的回调函数
  modifyText = (key) => {
    let that = this;
    return function (e) {
      // context为拿到输入框的dom结点
      let context;
      if (key === 'title') {
        context = that.titleText;
        that.setState({ titleTextSelect: true });
      } else if (key === 'input') {
        context = that.inputText;
        that.setState({ inputTextSelect: true });
      } else if (key === 'output') {
        context = that.outputText;
        that.setState({ outputTextSelect: true });
      }
      // 通过context.focus()让光标聚于输入框中
      context.focus();
      context.selectionStart = context.value.length;
      // 如果没有添加过监听函数，则添加clickOutSide函数监听全局点击事件
      if (that.listenFunc === null) {
        that.listenFunc = that.clickOutSide(key)
        document.addEventListener('click', that.listenFunc, false);
      }
    }

  }
  // clickOutSide函数用于点击输入框以外时发生的回调
  clickOutSide = (key) => {
    let that = this;
    // 因为要传入key识别是哪个输入框，只能直接调用clickOutSide(key)
    // 返回的这个函数才是真正的回调函数
    return async function (e) {
      // 判断是哪个输入框正在输入
      let contextClass;
      if (key === 'title') {
        contextClass = 'title-text title-selected';
      } else if (key === 'input') {
        contextClass = 'input-text input-selected';
      } else if (key === 'output') {
        contextClass = 'output-text output-selected';
      }
      // 点击输入框外边时把对应的xxxTextSelect设置为false表示输入完成，输入框已不被选中
      if (e.target.className === undefined ||
        (
          e.target.className !== contextClass &&
          e.target.className !== 'fa fa-pencil')) {
        if (key === 'title') {
          that.setState({ titleTextSelect: false });
        } else if (key === 'input') {
          that.setState({ inputTextSelect: false });
        } else if (key === 'output') {
          that.setState({ outputTextSelect: false });
        }
        // 输入完成后从父组件传入的参数中拿到数据并将数据传入轻服务中
        const { id, title, input, output, interviewId } = that.props;
        const newQuestion = {
          id: id,
          title: title,
          input: input,
          output: output,
          interviewId: interviewId,
        }
        await axios.post('https://qcge2v.fn.thelarkcloud.com/addQuestion', newQuestion)
        // 之前点击修改按钮后添加的全局监听事件务必要删掉
        document.removeEventListener('click', that.listenFunc, false);
        // 并把这个函数的引用清除
        that.listenFunc = null;
        that.state.client.sendQuestionUpdate('sendQuestionUpdate');
      }
    }
  }
  // 当title input output输入框改变时调用onChangeHandler返回的回调函数
  onChangeHandler = (key, handler) => {
    let that = this;
    // 因为要传入key, handler识别是哪个输入框，只能直接调用onChangeHandler(key, handler)
    // 返回的这个函数才是真正的回调函数
    return function (e) {
      let context;
      if (key === 'title') {
        context = that.titleText;
        // 这里传入的handler是父组件传入当前组件的回调函数，通过这个函数吧输入框的值传回去
        handler(context.value, that.index)
      } else if (key === 'input') {
        context = that.inputText;
        handler(context.value, that.index)
      } else if (key === 'output') {
        context = that.outputText;
        handler(context.value, that.index)
      }
    }
  }
  componentDidMount () {
    // 通过dom结点拿到div的高度用于问题框展示隐藏时的伸缩动画
    this.item.style.setProperty('--maxHeight', this.item.clientHeight + 'px')
  }
}